package org.example.servicelogin.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.model.manage.bean.po.security.User;
import org.example.servicelogin.mapper.CounselorMapper;
import org.example.servicelogin.mapper.FacultyMapper;
import org.example.servicelogin.mapper.OfficeMapper;
import org.example.servicelogin.mapper.UserMapper;
import org.example.model.manage.bean.po.security.MyUserDetails;
import org.example.servicelogin.service.UserService;
import org.example.servicelogin.utils.JwtUtil;
import org.example.servicelogin.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2025-07-16
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OfficeMapper officeMapper;

    @Autowired
    private FacultyMapper facultyMapper;

    @Autowired
    private CounselorMapper counselorMapper;

    @Override
    public void createUser(User user) {
        System.out.println(user);
        if(!userMapper.selectList(new QueryWrapper<User>().eq("account", user.getAccount())).isEmpty()) {
            throw new RuntimeException("用户已存在");
        }
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        userMapper.insert(user);
    }

    @Override
    public String login(String account, String password) {

        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(account, password);
        Authentication authentication = authenticationManager.authenticate(token);

        MyUserDetails user = (MyUserDetails) authentication.getPrincipal();
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getUser().getId());
        String JWT = "Bearer " + JwtUtil.generateToken(map);

        redisTemplate.opsForHash().put("login:" + user.getUser().getId(), "user", user);
        redisTemplate.opsForHash().put("login:" + user.getUser().getId(), "jwt", JWT);

        return JWT;
    }

    @Override
    public void logout(String token) {
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }

        // 通过token查找用户ID
        Set<String> keys = redisTemplate.keys("login:*");

        if (keys != null) {
            for (String key : keys) {
                Object storedToken = redisTemplate.opsForHash().get(key, "jwt");
                if (storedToken != null && ("Bearer " + token).equals(storedToken.toString())) {
                    // 找到匹配的token，删除它
                    redisTemplate.opsForHash().delete(key, "jwt");
                    System.out.println(keys);
                    break;
                }
            }
        }
    }

    @Override
    public UserVo getUserInfo() {
        User user = ((MyUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUser();
        if(user.getType().equals("office")) {
            return new UserVo(user, officeMapper.selectById(user.getTypeId()).getName());
        } else if(user.getType().equals("faculty")) {
            return new UserVo(user, facultyMapper.selectById(user.getTypeId()).getFaculty());
        } else if(user.getType().equals("counselor")) {
            return new UserVo(user, counselorMapper.selectById(user.getTypeId()).getName());
        } else {
            return new UserVo(user, null);
        }
    }
}
